﻿#region Header

/*
Remote views based on linq
By

Pascal Hauser 
Dipl. Ing. in Informatik, Hochschule für Technik Rapperswil, 2006
Master Thesis, Hochschule für Technik Rapperswil, 2008-2010

and

Raphael Gfeller
Dipl. Ing. in Informatik, Hochschule für Technik Rapperswil, 2006
Master Thesis, Hochschule für Technik Rapperswil, 2008-2010

*/

#endregion

#region Usings

using System;
using System.Collections.Generic;
using System.Linq;
using Sebarf.Core;
using Sebarf.Core.Interfaces;
using Sebarf.Diagnostics.Interfaces;
using Sebarf.Services.Interfaces;

#endregion

namespace Sebarf.Services.Impl {
	/// <summary>
	/// Description of the class
	/// </summary>
	public class ServiceRegistrationLocatorService : Service, IServiceLocatorService, IServiceRegistrationService,
													 IDiagnosticsServiceLocatorService {
		#region Public Properties

		public ServiceRegistrationLocatorService() {
			RegisterService(this);
		}

		#region IServiceLocatorService Members

		public TServiceType GetRegisteredService<TServiceType>() where TServiceType : class {
			IEnumerable<object> toReturn = (from service in m_availableServices where service is TServiceType select service);
			object[] services = toReturn.ToArray();
			Check.AssertException(services.Length <= 1,
								   "no more than one service should be available of type : " + typeof(TServiceType));
			if (services.Length == 0) {
				return null;
			}
			return services[0] as TServiceType;
		}

		public TServiceType[] GetRegisteredServices<TServiceType>() where TServiceType : class {
			var toReturn = new List<TServiceType>();
			foreach (object s in (from service in m_availableServices where service is TServiceType select service).ToArray()) {
				toReturn.Add(s as TServiceType);
			}
			return toReturn.ToArray();
		}

		public bool IsServiceAvailable<TServiceType>() where TServiceType : class {
			return GetRegisteredService<TServiceType>() != null;
		}

		#endregion

		#region IServiceRegistrationService Members

		public void RegisterService<TServiceType>(TServiceType service) where TServiceType : class {
			if (!m_availableServices.Contains(service)) {
				m_availableServices.Add(service);
			}
		}

		public void RegisterService(object service) {
			if (!m_availableServices.Contains(service)) {
				m_availableServices.Add(service);
			}
		}

		#endregion

		private object GetRegisteredService(Type t) {
			foreach (object service in m_availableServices) {
				if (t.IsAssignableFrom(service.GetType())) {
					return service;
				}
			}
			return null;
		}

		protected Object[] GetRegisteredServices() {
			return m_availableServices.ToArray();
		}

		#endregion

		#region Private Fields

		private readonly List<Object> m_availableServices = new List<object>();

		#endregion

		#region IDiagnosticsServiceLocatorService Members

		public T[] GetAllRegisteredServices<T>() {
			var toReturn = new List<T>();
			foreach (object service in m_availableServices) {
				if (service is T && !toReturn.Contains((T)service)) {
					toReturn.Add((T)service);
				}
			}
			return toReturn.ToArray();
		}

		#endregion
	}
}